1 Set-up

1.1 libs

suppressPackageStartupMessages({
    library(tidyverse)
    library(lubridate)
    library(broom)
    library(psych)
    library(heatmaply)
    library(patchwork)
})

1.2 Data Read-In

1.2.1 tRNA array probes

tRNAprobes <- 
read_delim( 
    delim = "\t",
    file = "../tRNA-GtRNAdb/450k_coresponding_hg19tRNAs.bed",
    col_types = "ciicciiciciicccc",
    col_names = c("pChr","pStart","pEnd","probeID",
        as.character(
            read_delim(
                delim = "\t",
                file = "../tRNA-GtRNAdb/std_tRNA_header.txt",
                col_names = FALSE,
                col_types = paste0(rep("c",12),collapse = "")
            )
        )
    )
)

1.2.2 tRNAge gene set

tRNAge <- read_delim(
    delim = "\t",
     col_names = "tRNAname",
     col_types = "c",
     file = "../tRNA-GtRNAdb/GenWideSigWintRNAs.txt"
) %>%
    pull()

1.2.3 Methylation Data

dataTest <- readRDS(
    file = "data/tRNAprobesNormCancerArrayPairs.Rds"
)
tRNAmethCancerNormal <- dataTest %>% 
    unnest() %>% 
    as_tibble() %>%
    filter(sample_type %in% c("Solid Tissue Normal","Primary Tumor")) %>%
    mutate(tRNAge = tRNAname %in% tRNAge) %>%
    filter(!is.na(Beta_value))
`cols` is now required.
Please use `cols = c(data)`

2 tRNA subsets

tRNAmethCancerNormal %>%
    mutate(tRNAge=as.character(tRNAge)) %>%
    mutate(tRNAge=if_else(tRNAge==TRUE,"tRNAge (MeDIP-seq 38)","Other tRNAs")) %>%
    ggplot(aes(sample_type,Beta_value)) + 
        geom_jitter(size=0.01) +
        geom_violin(aes(fill=sample_type),alpha=0.6,draw_quantiles = c(0.25,0.5,0.75)) +
        facet_wrap(~tRNAge)

tRNAsCovered <- tRNAmethCancerNormal %>% distinct(tRNAname) %>% pull()
tRNAsCovered
 [1] "tRNA-iMet-CAT-1-3" "tRNA-Met-CAT-3-2"  "tRNA-Gly-GCC-2-3"  "tRNA-Gly-CCC-2-2" 
 [5] "tRNA-Leu-AAG-2-2"  "tRNA-Asn-GTT-1-1"  "tRNA-Trp-CCA-5-1"  "tRNA-Tyr-GTA-1-1" 
 [9] "tRNA-Ser-TGA-2-1"  "tRNA-Gly-CCC-2-1"  "tRNA-Ala-CGC-2-1"  "tRNA-Ser-GCT-2-1" 
[13] "tRNA-Val-CAC-1-4"  "tRNA-Leu-AAG-2-4"  "tRNA-Ser-AGA-2-2"  "tRNA-Leu-TAG-3-1" 
[17] "tRNA-Ser-AGA-2-3"  "tRNA-His-GTG-1-8"  "tRNA-Ser-TGA-1-1"  "tRNA-Ser-AGA-2-6" 
[21] "tRNA-Leu-TAG-1-1"  "tRNA-Lys-TTT-3-2"  "tRNA-iMet-CAT-1-4" "tRNA-Val-TAC-4-1" 
[25] "tRNA-Ala-AGC-2-1"  "tRNA-Tyr-GTA-3-1"  "tRNA-Arg-CCG-1-2"  "tRNA-Phe-GAA-1-3" 
[29] "tRNA-Glu-TTC-2-1"  "tRNA-Ser-AGA-2-5"  "tRNA-Val-AAC-1-4"  "tRNA-His-GTG-1-9" 
[33] "tRNA-His-GTG-1-7"  "tRNA-Val-CAC-4-1"  "tRNA-Asp-GTC-2-8"  "tRNA-Trp-CCA-1-1" 
[37] "tRNA-Glu-CTC-3-1"  "tRNA-Lys-TTT-3-4"  "tRNA-Val-AAC-2-1"  "tRNA-Asn-ATT-1-1" 
[41] "tRNA-Ser-CGA-3-1"  "tRNA-Pro-AGG-2-8"  "tRNA-Asp-GTC-2-6"  "tRNA-Ser-AGA-4-1" 
[45] "tRNA-Met-CAT-4-2" 
tRNAsCovered %>% length()
[1] 45
tRNAgeCovered <- tRNAge[tRNAge %in% tRNAsCovered]
tRNAgeCovered
[1] "tRNA-Arg-CCG-1-2"  "tRNA-iMet-CAT-1-4" "tRNA-Met-CAT-4-2"  "tRNA-Ser-AGA-2-6" 
[5] "tRNA-Ser-TGA-2-1"  "tRNA-Val-CAC-4-1"  "tRNA-Val-TAC-4-1" 
tRNAgeCovered %>% length()
[1] 7

2.1 tRNAge/other genes methylation with age in cancer and normal tissues

tRNAgeCancerNormal <- 
tRNAmethCancerNormal %>% 
    mutate(tRNAge = as.character(tRNAge)) %>%
    mutate(
        tRNAge = if_else(
            tRNAge==TRUE,
            "tRNAge (MeDIP-seq 38)",
            "Other tRNAs"
        )
    ) %>%
    ggplot(aes(age,Beta_value)) + 
        geom_point(size = 0.01) + 
        geom_smooth(method = "lm") + 
        geom_text(
            y = 0.94, x = 18, colour = "red",
            aes(label = paste0("r = ", round(r,4))),
            data = tRNAmethCancerNormal %>%
                mutate(tRNAge = as.character(tRNAge)) %>%
                mutate(tRNAge = if_else(
                    tRNAge == TRUE,
                    "tRNAge (MeDIP-seq 38)",
                    "Other tRNAs")
                ) %>%
                group_by(tRNAge,sample_type) %>%
                summarise(r = cor(age,Beta_value))
        ) +
        facet_grid(sample_type ~ tRNAge) + 
        labs(title = "tRNA gene methylation with age accross all tissues")

tRNAgeCancerNormal

#dir.create("../graphics")
# ggsave(tRNAgeCancerNormal,filename = "../graphics/tRNAgeCancerNormal.png",width = 12,height = 6.75)

2.2 tRNAge/other genes methylation with age by tissue of origin

ageRange <- range(tRNAmethCancerNormal$age)

rsByTissue <- tRNAmethCancerNormal %>%
    mutate(tRNAge=as.character(tRNAge)) %>%
    mutate(tRNAge=if_else(tRNAge==TRUE,"tRNAge (MeDIP-seq 38)","Other tRNAs")) %>%
    group_by(tRNAge,sample_type,primary_site) %>%
    summarise(r=cor(age,Beta_value))
the standard deviation is zerothe standard deviation is zerothe standard deviation is zerothe standard deviation is zero
tRNAgeCancerNormalbyTissue <- 
tRNAmethCancerNormal %>% 
    mutate(tRNAge=as.character(tRNAge)) %>%
    mutate(tRNAge=if_else(tRNAge==TRUE,"tRNAge (MeDIP-seq 38)","Other tRNAs")) %>%
    group_by(primary_site) %>%
    do(plot=
        ggplot(.,aes(age,Beta_value)) + 
            geom_point(size=0.01) + 
            geom_smooth(method = "lm") + 
            xlim(ageRange) +
            ylim(0,1) +
            geom_text(y=0.94,x=18,colour="red",  #####!!!!!!!
                      aes(label=paste0("r = ",round(r,4))),
                data = rsByTissue[rsByTissue$primary_site==.$primary_site[1],]
            ) +
            facet_grid(sample_type~tRNAge) + 
            labs(title = paste0("tRNA gene methylation in ",.$primary_site))
    )

tRNAgeCancerNormalbyTissue$plot
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

[[8]]

[[9]]

[[10]]

[[11]]

[[12]]

[[13]]

[[14]]

[[15]]

[[16]]

[[17]]

[[18]]

[[19]]


3 tRNA-iMet-CAT-1-4

much higher mean methylation in these samples than in fetal samples (~0.125), quite a lot of variance here especially in the tumour

tRNAmethCancerNormal %>%
    dplyr::filter(tRNAname == "tRNA-iMet-CAT-1-4") %>%
    ggplot(aes(age,Beta_value)) +
        geom_point(aes(shape=sample_type,colour=sample_type)) + 
        scale_shape_manual(values = c(3,4)) +
        geom_smooth(aes(colour=sample_type),method = "lm") + 
        scale_colour_manual(values = c("red","black")) +
        facet_wrap(~tRNAname)


extracting codon/aa/ncular mitochondrial data from tRNA names

tRNAmethCancerNormal <- 
tRNAmethCancerNormal %>%
    tidyr::extract(tRNAname,
            c("nmt","aa","codon"),
            "(\\w*)-?tRNA-(i?\\w{3})(?:\\w+)?-(\\w+)-",
            remove = FALSE
    )
# custom labeler: (character vector in and out)
tRNA_labeller <- function(value) {sapply(value,
    function(n){
    tRNAmethCancerNormal %>%
        dplyr::select(tRNAname,tChr,strand) %>%
        distinct() %>%
        dplyr::filter(tRNAname==as.character(n)) %>%
        unlist() %>%
        (function(d) paste0(d["tRNAname"]," (",d["strand"],") ",tools::toTitleCase(d["tChr"]))) %>%
        return()
    }
)}

plots <- tRNAmethCancerNormal %>%
    group_by(aa) %>%
    do(plot=
        ggplot(.,aes(age,Beta_value)) +
            geom_point(aes(shape=sample_type,colour=sample_type)) + 
            scale_shape_manual(values = c(3,4)) +
            geom_smooth(aes(colour=sample_type),method = "lm") + 
            scale_colour_manual(values = c("red","black")) +
            facet_wrap(~tRNAname, labeller = labeller(tRNAname = tRNA_labeller)) +
            labs(title = paste0("tRNA genes of ",.$aa," isotype"),
                 x="Age /yrs"
            )
    )
plots$plot
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

[[8]]

[[9]]

[[10]]

[[11]]

[[12]]

[[13]]

[[14]]

[[15]]

[[16]]

[[17]]

# #dir.create("../graphics/tRNAMethAgeCancerVsNormalBytRNA")
# nil <- plots %>% do(out=ggsave(plot = .$plot,
#                   filename = paste0("../graphics/tRNAMethAgeCancerVsNormalBytRNA/tRNAMethAgeCancerVsNormal_" , .$aa , ".png"),
#                   width = 8,
#                   height = 4.5
#               ))
# rm(nil)
plots <- tRNAmethCancerNormal %>%
    group_by(aa,primary_site) %>%
    do(plot=
        ggplot(.,aes(age,Beta_value)) +
            geom_point(aes(shape=sample_type,colour=sample_type)) + 
            scale_shape_manual(values = c(3,4)) +
            geom_smooth(aes(colour=sample_type),method = "lm") + 
            scale_colour_manual(values = c("red","black")) +
            facet_wrap(~tRNAname, labeller = labeller(tRNAname = tRNA_labeller)) +
            labs(title = paste0("tRNA genes of ",.$aa," isotype for ",.$primary_site),
                 x="Age /yrs"
            )
    )
#plots$plot
# # dir.create("../graphics/tRNAMethAgeCancerVsNormalByTissue")
# nil <- plots %>% do(out=ggsave(plot = .$plot,
#                   filename = paste0("../graphics/tRNAMethAgeCancerVsNormalByTissue/tRNAMethAgeCancerVsNormal_" , .$aa ,"_",.$primary_site, ".png"),
#                   width = 8,
#                   height = 4.5
#               ))
# rm(nil)

4 Session Info

sessionInfo()
R version 3.6.2 (2019-12-12)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.3 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C               LC_TIME=en_GB.UTF-8       
 [4] LC_COLLATE=en_GB.UTF-8     LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] heatmaply_0.16.0     viridis_0.5.1        viridisLite_0.3.0    plotly_4.9.1        
 [5] circlize_0.4.8       ComplexHeatmap_2.0.0 patchwork_0.0.1      psych_1.8.12        
 [9] broom_0.5.2          lubridate_1.7.4      forcats_0.4.0        stringr_1.4.0       
[13] dplyr_0.8.3          purrr_0.3.3          readr_1.3.1          tidyr_1.0.0         
[17] tibble_2.1.3         ggplot2_3.2.1        tidyverse_1.2.1      testthat_2.3.0      
[21] devtools_2.2.1       usethis_1.5.1        reprex_0.3.0        

loaded via a namespace (and not attached):
  [1] colorspace_1.4-1    rjson_0.2.20        ellipsis_0.3.0      rprojroot_1.3-2    
  [5] GlobalOptions_0.1.1 base64enc_0.1-3     fs_1.3.1            clue_0.3-57        
  [9] rstudioapi_0.10     remotes_2.1.0       xml2_1.2.2          codetools_0.2-16   
 [13] mnormt_1.5-5        knitr_1.25          pkgload_1.0.2       zeallot_0.1.0      
 [17] jsonlite_1.6        Cairo_1.5-10        packrat_0.5.0       cluster_2.1.0      
 [21] png_0.1-7           shiny_1.4.0         compiler_3.6.2      httr_1.4.1         
 [25] backports_1.1.5     fastmap_1.0.1       assertthat_0.2.1    lazyeval_0.2.2     
 [29] cli_1.1.0           later_1.0.0         htmltools_0.4.0     prettyunits_1.0.2  
 [33] tools_3.6.2         gtable_0.3.0        glue_1.3.1          reshape2_1.4.3     
 [37] Rcpp_1.0.3          cellranger_1.1.0    vctrs_0.2.0         gdata_2.18.0       
 [41] nlme_3.1-143        crosstalk_1.0.0     iterators_1.0.12    xfun_0.10          
 [45] ps_1.3.0            rvest_0.3.5         mime_0.7            lifecycle_0.1.0    
 [49] gtools_3.8.1        dendextend_1.12.0   MASS_7.3-51.5       scales_1.0.0       
 [53] TSP_1.1-7           promises_1.1.0      hms_0.5.2           parallel_3.6.2     
 [57] RColorBrewer_1.1-2  yaml_2.2.0          memoise_1.1.0       gridExtra_2.3      
 [61] stringi_1.4.3       gclus_1.3.2         desc_1.2.0          foreach_1.4.7      
 [65] seriation_1.2-8     caTools_1.17.1.2    pkgbuild_1.0.6      shape_1.4.4        
 [69] rlang_0.4.1         pkgconfig_2.0.3     bitops_1.0-6        evaluate_0.14      
 [73] lattice_0.20-38     htmlwidgets_1.5.1   labeling_0.3        processx_3.4.1     
 [77] tidyselect_0.2.5    plyr_1.8.4          magrittr_1.5        R6_2.4.0           
 [81] gplots_3.0.1.1      generics_0.0.2      pillar_1.4.2        haven_2.2.0        
 [85] foreign_0.8-72      withr_2.1.2         modelr_0.1.5        crayon_1.3.4       
 [89] KernSmooth_2.23-16  rmarkdown_1.16      GetoptLong_0.1.7    readxl_1.3.1       
 [93] data.table_1.12.6   callr_3.3.2         digest_0.6.22       webshot_0.5.1      
 [97] xtable_1.8-4        httpuv_1.5.2        munsell_0.5.0       registry_0.5-1     
[101] sessioninfo_1.1.1  

5 References

LS0tCnRpdGxlOiAiMDQgLSBHZW5vbWljRGF0YUNvbW1vbnMgTm9ybWFsIFZzLiBDYW5jZXIgdGlzc3VlIHRSTkEgZ2VuZSBtZXRoeWxhdGlvbiAtIHRSTkFnZSBzZXRzICYgbWV0aCBieSB0Uk5BIgphdXRob3I6ICJSaWNoYXJkIEouIEFjdG9uIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKYmlibGlvZ3JhcGh5OiAiYHIgbm9ybWFsaXplUGF0aCgnLi4vbGlicmFyeS5iaWInKWAiCi0tLQoKIyBTZXQtdXAKCiMjIGxpYnMKCmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewoJbGlicmFyeSh0aWR5dmVyc2UpCglsaWJyYXJ5KGx1YnJpZGF0ZSkKCWxpYnJhcnkoYnJvb20pCglsaWJyYXJ5KHBzeWNoKQoJbGlicmFyeShoZWF0bWFwbHkpCglsaWJyYXJ5KHBhdGNod29yaykKfSkKYGBgCgojIyBEYXRhIFJlYWQtSW4KCiMjIyB0Uk5BIGFycmF5IHByb2JlcwoKYGBge3J9CnRSTkFwcm9iZXMgPC0gCnJlYWRfZGVsaW0oCQoJZGVsaW0gPSAiXHQiLAoJZmlsZSA9ICIuLi90Uk5BLUd0Uk5BZGIvNDUwa19jb3Jlc3BvbmRpbmdfaGcxOXRSTkFzLmJlZCIsCgljb2xfdHlwZXMgPSAiY2lpY2NpaWNpY2lpY2NjYyIsCgljb2xfbmFtZXMgPSBjKCJwQ2hyIiwicFN0YXJ0IiwicEVuZCIsInByb2JlSUQiLAoJCWFzLmNoYXJhY3RlcigKCQkJcmVhZF9kZWxpbSgKCQkJCWRlbGltID0gIlx0IiwKCQkJCWZpbGUgPSAiLi4vdFJOQS1HdFJOQWRiL3N0ZF90Uk5BX2hlYWRlci50eHQiLAoJCQkJY29sX25hbWVzID0gRkFMU0UsCgkJCQljb2xfdHlwZXMgPSBwYXN0ZTAocmVwKCJjIiwxMiksY29sbGFwc2UgPSAiIikKCQkJKQoJCSkKCSkKKQoKYGBgCgojIyMgdFJOQWdlIGdlbmUgc2V0CgpgYGB7cn0KdFJOQWdlIDwtIHJlYWRfZGVsaW0oCglkZWxpbSA9ICJcdCIsCgkgY29sX25hbWVzID0gInRSTkFuYW1lIiwKCSBjb2xfdHlwZXMgPSAiYyIsCgkgZmlsZSA9ICIuLi90Uk5BLUd0Uk5BZGIvR2VuV2lkZVNpZ1dpbnRSTkFzLnR4dCIKKSAlPiUKCXB1bGwoKQpgYGAKCiMjIyBNZXRoeWxhdGlvbiBEYXRhCgpgYGB7cn0KZGF0YVRlc3QgPC0gcmVhZFJEUygKCWZpbGUgPSAiZGF0YS90Uk5BcHJvYmVzTm9ybUNhbmNlckFycmF5UGFpcnMuUmRzIgopCmBgYAoKYGBge3J9CnRSTkFtZXRoQ2FuY2VyTm9ybWFsIDwtIGRhdGFUZXN0ICU+JSAKCXVubmVzdCgpICU+JSAKCWFzX3RpYmJsZSgpICU+JQoJZmlsdGVyKHNhbXBsZV90eXBlICVpbiUgYygiU29saWQgVGlzc3VlIE5vcm1hbCIsIlByaW1hcnkgVHVtb3IiKSkgJT4lCgltdXRhdGUodFJOQWdlID0gdFJOQW5hbWUgJWluJSB0Uk5BZ2UpICU+JQoJZmlsdGVyKCFpcy5uYShCZXRhX3ZhbHVlKSkKCmBgYAoKIyB0Uk5BIHN1YnNldHMKCmBgYHtyfQp0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCW11dGF0ZSh0Uk5BZ2U9YXMuY2hhcmFjdGVyKHRSTkFnZSkpICU+JQoJbXV0YXRlKHRSTkFnZT1pZl9lbHNlKHRSTkFnZT09VFJVRSwidFJOQWdlIChNZURJUC1zZXEgMzgpIiwiT3RoZXIgdFJOQXMiKSkgJT4lCglnZ3Bsb3QoYWVzKHNhbXBsZV90eXBlLEJldGFfdmFsdWUpKSArIAoJCWdlb21faml0dGVyKHNpemU9MC4wMSkgKwoJCWdlb21fdmlvbGluKGFlcyhmaWxsPXNhbXBsZV90eXBlKSxhbHBoYT0wLjYsZHJhd19xdWFudGlsZXMgPSBjKDAuMjUsMC41LDAuNzUpKSArCgkJZmFjZXRfd3JhcCh+dFJOQWdlKQpgYGAKCmBgYHtyfQp0Uk5Bc0NvdmVyZWQgPC0gdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lIGRpc3RpbmN0KHRSTkFuYW1lKSAlPiUgcHVsbCgpCnRSTkFzQ292ZXJlZAp0Uk5Bc0NvdmVyZWQgJT4lIGxlbmd0aCgpCmBgYAoKYGBge3J9CnRSTkFnZUNvdmVyZWQgPC0gdFJOQWdlW3RSTkFnZSAlaW4lIHRSTkFzQ292ZXJlZF0KdFJOQWdlQ292ZXJlZAp0Uk5BZ2VDb3ZlcmVkICU+JSBsZW5ndGgoKQpgYGAKCiMjIHRSTkFnZS9vdGhlciBnZW5lcyBtZXRoeWxhdGlvbiB3aXRoIGFnZSBpbiBjYW5jZXIgYW5kIG5vcm1hbCB0aXNzdWVzCgpgYGB7cixmaWcud2lkdGg9MTIsZmlnLmhlaWdodD02Ljc1fQp0Uk5BZ2VDYW5jZXJOb3JtYWwgPC0gCnRSTkFtZXRoQ2FuY2VyTm9ybWFsICU+JSAKCW11dGF0ZSh0Uk5BZ2UgPSBhcy5jaGFyYWN0ZXIodFJOQWdlKSkgJT4lCgltdXRhdGUoCgkJdFJOQWdlID0gaWZfZWxzZSgKCQkJdFJOQWdlPT1UUlVFLAoJCQkidFJOQWdlIChNZURJUC1zZXEgMzgpIiwKCQkJIk90aGVyIHRSTkFzIgoJCSkKCSkgJT4lCglnZ3Bsb3QoYWVzKGFnZSxCZXRhX3ZhbHVlKSkgKyAKCQlnZW9tX3BvaW50KHNpemUgPSAwLjAxKSArIAoJCWdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCgkJZ2VvbV90ZXh0KAoJCQl5ID0gMC45NCwgeCA9IDE4LCBjb2xvdXIgPSAicmVkIiwKCQkJYWVzKGxhYmVsID0gcGFzdGUwKCJyID0gIiwgcm91bmQociw0KSkpLAoJCQlkYXRhID0gdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lCgkJCQltdXRhdGUodFJOQWdlID0gYXMuY2hhcmFjdGVyKHRSTkFnZSkpICU+JQoJCQkJbXV0YXRlKHRSTkFnZSA9IGlmX2Vsc2UoCgkJCQkJdFJOQWdlID09IFRSVUUsCgkJCQkJInRSTkFnZSAoTWVESVAtc2VxIDM4KSIsCgkJCQkJIk90aGVyIHRSTkFzIikKCQkJCSkgJT4lCgkJCQlncm91cF9ieSh0Uk5BZ2Usc2FtcGxlX3R5cGUpICU+JQoJCQkJc3VtbWFyaXNlKHIgPSBjb3IoYWdlLEJldGFfdmFsdWUpKQoJCSkgKwoJCWZhY2V0X2dyaWQoc2FtcGxlX3R5cGUgfiB0Uk5BZ2UpICsgCgkJbGFicyh0aXRsZSA9ICJ0Uk5BIGdlbmUgbWV0aHlsYXRpb24gd2l0aCBhZ2UgYWNjcm9zcyBhbGwgdGlzc3VlcyIpCgp0Uk5BZ2VDYW5jZXJOb3JtYWwKYGBgCgpgYGB7cn0KI2Rpci5jcmVhdGUoIi4uL2dyYXBoaWNzIikKIyBnZ3NhdmUodFJOQWdlQ2FuY2VyTm9ybWFsLGZpbGVuYW1lID0gIi4uL2dyYXBoaWNzL3RSTkFnZUNhbmNlck5vcm1hbC5wbmciLHdpZHRoID0gMTIsaGVpZ2h0ID0gNi43NSkKYGBgCgojIyB0Uk5BZ2Uvb3RoZXIgZ2VuZXMgbWV0aHlsYXRpb24gd2l0aCBhZ2UgYnkgdGlzc3VlIG9mIG9yaWdpbgoKYGBge3IsZmlnLndpZHRoPTEyLGZpZy5oZWlnaHQ9Ni43NX0KYWdlUmFuZ2UgPC0gcmFuZ2UodFJOQW1ldGhDYW5jZXJOb3JtYWwkYWdlKQoKcnNCeVRpc3N1ZSA8LSB0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCW11dGF0ZSh0Uk5BZ2U9YXMuY2hhcmFjdGVyKHRSTkFnZSkpICU+JQoJbXV0YXRlKHRSTkFnZT1pZl9lbHNlKHRSTkFnZT09VFJVRSwidFJOQWdlIChNZURJUC1zZXEgMzgpIiwiT3RoZXIgdFJOQXMiKSkgJT4lCglncm91cF9ieSh0Uk5BZ2Usc2FtcGxlX3R5cGUscHJpbWFyeV9zaXRlKSAlPiUKCXN1bW1hcmlzZShyPWNvcihhZ2UsQmV0YV92YWx1ZSkpCgp0Uk5BZ2VDYW5jZXJOb3JtYWxieVRpc3N1ZSA8LSAKdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lIAoJbXV0YXRlKHRSTkFnZT1hcy5jaGFyYWN0ZXIodFJOQWdlKSkgJT4lCgltdXRhdGUodFJOQWdlPWlmX2Vsc2UodFJOQWdlPT1UUlVFLCJ0Uk5BZ2UgKE1lRElQLXNlcSAzOCkiLCJPdGhlciB0Uk5BcyIpKSAlPiUKCWdyb3VwX2J5KHByaW1hcnlfc2l0ZSkgJT4lCglkbyhwbG90PQoJCWdncGxvdCguLGFlcyhhZ2UsQmV0YV92YWx1ZSkpICsgCgkJCWdlb21fcG9pbnQoc2l6ZT0wLjAxKSArIAoJCQlnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArIAoJCQl4bGltKGFnZVJhbmdlKSArCgkJCXlsaW0oMCwxKSArCgkJCWdlb21fdGV4dCh5PTAuOTQseD0xOCxjb2xvdXI9InJlZCIsICAjIyMjIyEhISEhISEKCQkJCQkgIGFlcyhsYWJlbD1wYXN0ZTAoInIgPSAiLHJvdW5kKHIsNCkpKSwKCQkJCWRhdGEgPSByc0J5VGlzc3VlW3JzQnlUaXNzdWUkcHJpbWFyeV9zaXRlPT0uJHByaW1hcnlfc2l0ZVsxXSxdCgkJCSkgKwoJCQlmYWNldF9ncmlkKHNhbXBsZV90eXBlfnRSTkFnZSkgKyAKCQkJbGFicyh0aXRsZSA9IHBhc3RlMCgidFJOQSBnZW5lIG1ldGh5bGF0aW9uIGluICIsLiRwcmltYXJ5X3NpdGUpKQoJKQoKdFJOQWdlQ2FuY2VyTm9ybWFsYnlUaXNzdWUkcGxvdApgYGAKCi0tLQoKIyB0Uk5BLWlNZXQtQ0FULTEtNAoKbXVjaCBoaWdoZXIgbWVhbiBtZXRoeWxhdGlvbiBpbiB0aGVzZSBzYW1wbGVzIHRoYW4gaW4gZmV0YWwgc2FtcGxlcyAofjAuMTI1KSwgcXVpdGUgYSBsb3Qgb2YgdmFyaWFuY2UgaGVyZSBlc3BlY2lhbGx5IGluIHRoZSB0dW1vdXIKCmBgYHtyfQp0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCWRwbHlyOjpmaWx0ZXIodFJOQW5hbWUgPT0gInRSTkEtaU1ldC1DQVQtMS00IikgJT4lCglnZ3Bsb3QoYWVzKGFnZSxCZXRhX3ZhbHVlKSkgKwoJCWdlb21fcG9pbnQoYWVzKHNoYXBlPXNhbXBsZV90eXBlLGNvbG91cj1zYW1wbGVfdHlwZSkpICsgCgkJc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMyw0KSkgKwoJCWdlb21fc21vb3RoKGFlcyhjb2xvdXI9c2FtcGxlX3R5cGUpLG1ldGhvZCA9ICJsbSIpICsgCgkJc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCJibGFjayIpKSArCgkJZmFjZXRfd3JhcCh+dFJOQW5hbWUpCmBgYAoKLS0tCgpleHRyYWN0aW5nIGNvZG9uL2FhL25jdWxhciBtaXRvY2hvbmRyaWFsIGRhdGEgZnJvbSB0Uk5BIG5hbWVzCgpgYGB7cn0KdFJOQW1ldGhDYW5jZXJOb3JtYWwgPC0gCnRSTkFtZXRoQ2FuY2VyTm9ybWFsICU+JQoJdGlkeXI6OmV4dHJhY3QodFJOQW5hbWUsCgkJCWMoIm5tdCIsImFhIiwiY29kb24iKSwKCQkJIihcXHcqKS0/dFJOQS0oaT9cXHd7M30pKD86XFx3Kyk/LShcXHcrKS0iLAoJCQlyZW1vdmUgPSBGQUxTRQoJKQpgYGAKCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9NC41fQojIGN1c3RvbSBsYWJlbGVyOiAoY2hhcmFjdGVyIHZlY3RvciBpbiBhbmQgb3V0KQp0Uk5BX2xhYmVsbGVyIDwtIGZ1bmN0aW9uKHZhbHVlKSB7c2FwcGx5KHZhbHVlLAoJZnVuY3Rpb24obil7Cgl0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCQlkcGx5cjo6c2VsZWN0KHRSTkFuYW1lLHRDaHIsc3RyYW5kKSAlPiUKCQlkaXN0aW5jdCgpICU+JQoJCWRwbHlyOjpmaWx0ZXIodFJOQW5hbWU9PWFzLmNoYXJhY3RlcihuKSkgJT4lCgkJdW5saXN0KCkgJT4lCgkJKGZ1bmN0aW9uKGQpIHBhc3RlMChkWyJ0Uk5BbmFtZSJdLCIgKCIsZFsic3RyYW5kIl0sIikgIix0b29sczo6dG9UaXRsZUNhc2UoZFsidENociJdKSkpICU+JQoJCXJldHVybigpCgl9Cil9CgpwbG90cyA8LSB0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCWdyb3VwX2J5KGFhKSAlPiUKCWRvKHBsb3Q9CgkJZ2dwbG90KC4sYWVzKGFnZSxCZXRhX3ZhbHVlKSkgKwoJCQlnZW9tX3BvaW50KGFlcyhzaGFwZT1zYW1wbGVfdHlwZSxjb2xvdXI9c2FtcGxlX3R5cGUpKSArIAoJCQlzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygzLDQpKSArCgkJCWdlb21fc21vb3RoKGFlcyhjb2xvdXI9c2FtcGxlX3R5cGUpLG1ldGhvZCA9ICJsbSIpICsgCgkJCXNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygicmVkIiwiYmxhY2siKSkgKwoJCQlmYWNldF93cmFwKH50Uk5BbmFtZSwgbGFiZWxsZXIgPSBsYWJlbGxlcih0Uk5BbmFtZSA9IHRSTkFfbGFiZWxsZXIpKSArCgkJCWxhYnModGl0bGUgPSBwYXN0ZTAoInRSTkEgZ2VuZXMgb2YgIiwuJGFhLCIgaXNvdHlwZSIpLAoJCQkJIHg9IkFnZSAveXJzIgoJCQkpCgkpCnBsb3RzJHBsb3QKYGBgCgpgYGB7cn0KIyAjZGlyLmNyZWF0ZSgiZ3JhcGhpY3MvdFJOQU1ldGhBZ2VDYW5jZXJWc05vcm1hbEJ5dFJOQSIpCiMgbmlsIDwtIHBsb3RzICU+JSBkbyhvdXQ9Z2dzYXZlKHBsb3QgPSAuJHBsb3QsCiMgCQkJCQlmaWxlbmFtZSA9IHBhc3RlMCgiZ3JhcGhpY3MvdFJOQU1ldGhBZ2VDYW5jZXJWc05vcm1hbEJ5dFJOQS90Uk5BTWV0aEFnZUNhbmNlclZzTm9ybWFsXyIgLCAuJGFhICwgIi5wbmciKSwKIyAJCQkJCXdpZHRoID0gOCwKIyAJCQkJCWhlaWdodCA9IDQuNQojIAkJCQkpKQojIHJtKG5pbCkKYGBgCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpwbG90cyA8LSB0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUKCWdyb3VwX2J5KGFhLHByaW1hcnlfc2l0ZSkgJT4lCglkbyhwbG90PQoJCWdncGxvdCguLGFlcyhhZ2UsQmV0YV92YWx1ZSkpICsKCQkJZ2VvbV9wb2ludChhZXMoc2hhcGU9c2FtcGxlX3R5cGUsY29sb3VyPXNhbXBsZV90eXBlKSkgKyAKCQkJc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMyw0KSkgKwoJCQlnZW9tX3Ntb290aChhZXMoY29sb3VyPXNhbXBsZV90eXBlKSxtZXRob2QgPSAibG0iKSArIAoJCQlzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsImJsYWNrIikpICsKCQkJZmFjZXRfd3JhcCh+dFJOQW5hbWUsIGxhYmVsbGVyID0gbGFiZWxsZXIodFJOQW5hbWUgPSB0Uk5BX2xhYmVsbGVyKSkgKwoJCQlsYWJzKHRpdGxlID0gcGFzdGUwKCJ0Uk5BIGdlbmVzIG9mICIsLiRhYSwiIGlzb3R5cGUgZm9yICIsLiRwcmltYXJ5X3NpdGUpLAoJCQkJIHg9IkFnZSAveXJzIgoJCQkpCgkpCiNwbG90cyRwbG90CmBgYAoKYGBge3J9CiMgIyBkaXIuY3JlYXRlKCJncmFwaGljcy90Uk5BTWV0aEFnZUNhbmNlclZzTm9ybWFsQnlUaXNzdWUiKQojIG5pbCA8LSBwbG90cyAlPiUgZG8ob3V0PWdnc2F2ZShwbG90ID0gLiRwbG90LAojIAkJCQkJZmlsZW5hbWUgPSBwYXN0ZTAoImdyYXBoaWNzL3RSTkFNZXRoQWdlQ2FuY2VyVnNOb3JtYWxCeVRpc3N1ZS90Uk5BTWV0aEFnZUNhbmNlclZzTm9ybWFsXyIgLCAuJGFhICwiXyIsLiRwcmltYXJ5X3NpdGUsICIucG5nIiksCiMgCQkJCQl3aWR0aCA9IDgsCiMgCQkJCQloZWlnaHQgPSA0LjUKIyAJCQkJKSkKIyBybShuaWwpCmBgYAoKIyBTZXNzaW9uIEluZm8KCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKIyBSZWZlcmVuY2VzCgo=